<?php
/**
 * Ecma-262 5rd 7.8.3
 *
 */
class NumericLiteral extends Token{
    
    public function __construct() {
        parent::__construct ();
        $this->tokenType = Token::NumericLiteral;
    }
    
    /**
     * 
     * 获取DecimalLiteral ,参考7.8.3
     * DecimalLiteral ::
     *     DecimalIntegerLiteral . DecimalDigitsopt ExponentPartopt 
     *     . DecimalDigits ExponentPartopt 
     *     DecimalIntegerLiteral ExponentPartopt
     * 
     * 
     * @param string $stream
     * @param int $pos
     */
    public static function getDecimalLiteral(&$stream,$pos){
        $number = '';
        $decimalIntegerLiteral = '';
        $dot = '.';
        $decimalDigits = '';
        $exponentPart = '';
        
        $char = $stream[$pos];
        if(self::isDecimalDigit($char)){
            if($char === '0'){
                $decimalIntegerLiteral .= $char;
                $pos++;
            }
            else{
                for (;;){
                    $tempChar = $stream[$pos];
                    if(self::isDecimalDigit($tempChar)){
                        $decimalIntegerLiteral .= $tempChar;
                        $pos++;
                    }else{
                        break;
                    }
                }
            }
            
            $number = $decimalIntegerLiteral;
            $char = $stream[$pos];
            if($char === $dot){
                $number .= $dot;
                $pos++;
                for (;;){
                    $tempChar = $stream[$pos];
                    if(self::isDecimalDigit($tempChar)){
                        $decimalDigits .= $tempChar;
                        $pos++;
                    }else{
                        break;
                    }
                }
                $number .= $decimalDigits;
            }
            
            $char = $stream[$pos];
            if($char === 'e' || $char === 'E'){
                $exponentPart .= $char;
                $pos++;
                for (;;){
                    $tempChar = $stream[$pos];
                    if(self::isDecimalDigit($tempChar)){
                        $exponentPart .= $tempChar;
                        $pos++;
                    }else{
                        break;
                    }
                }
                if($exponentPart === $char){
                    return false;
                }
                $number .= $exponentPart;
                
            }
            
            return $number;
        }
        else if($char === $dot){
            $number = $dot;
            $pos++;
            $tempChar = $stream[$pos];
            if(self::isDecimalDigit($tempChar)){
                for (;;){
                    $tempChar = $stream[$pos];
                    if(self::isDecimalDigit($tempChar)){
                        $decimalDigits .= $tempChar;
                        $pos++;
                    }else{
                        break;
                    }
                }
            }
            else{
                return false;
            }
                
            $number .= $decimalDigits;
            
            $char = $stream[$pos];
            if($char === 'e' || $char === 'E'){
                $exponentPart .= $char;
                $pos++;
                for (;;){
                    $tempChar = $stream[$pos];
                    if(self::isDecimalDigit($tempChar)){
                        $exponentPart .= $tempChar;
                        $pos++;
                    }else{
                        break;
                    }
                }
                if($exponentPart === $char){
                    return false;
                }
                $number .= $exponentPart;
            }
            
            return $number;
            
        }
        else{
            return false;
        }
    }
    
    /**
     * 
     * 获取HexIntegerLiteral ,参考7.8.3
     * HexIntegerLiteral ::
     *     0x HexDigit 
     *     0X HexDigit 
     *     HexIntegerLiteral HexDigit
     * 
     * 
     * @param string $stream
     * @param int $pos
     */
    public static function getHexIntegerLiteral(&$stream,$pos){
        $number = '';
        
        $char0 = $stream[$pos+0];
        $char1 = $stream[$pos+1];
        $char2 = $stream[$pos+2];
        if($char0 === '0' && $char1 === 'x'){
            if(self::isHexDigit($char2)){
                $number .= '0x';
                
                for ($i=2;;$i++){
                    $tempChar = $stream[$pos+$i];
                    if(self::isHexDigit($tempChar)){
                        $number .= $tempChar;
                    }else{
                        break;
                    }
                }
                
                return $number;
            }
            
            return false;
        }
        
        return false;
    }
    
    public static function isDecimalDigit($char){
        if(in_array($char, array('0','1','2','3','4','5','6','7','8','9'))){
            return true;
        }
        
        return false;
    }
    
    public static function isNonZeroDigit($char){
        if(in_array($char, array(    '1','2','3','4','5','6','7','8','9'))){
            return true;
        }
        
        return false;
    }
    
    public static function isHexDigit($char){
        if(in_array($char, array('0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f','A','B','C','D','E','F'))){
            return true;
        }
        
        return false;
    }
    
    public static function isNumericLiteralStart($char){
        if(self::isDecimalDigit($char)){
            return true;
        }
        
        if($char === "."){
            return true;
        }
        
        return false;
    }
}